package com.CodeCraft.builder;

import com.CodeCraft.bean.Constants;
import com.CodeCraft.bean.FiledInfo;
import com.CodeCraft.bean.TableInfo;
import com.CodeCraft.utils.DateUtils;
import com.CodeCraft.utils.StringUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 描述:
 * </p>
 *
 * @author Dorain
 * @version 1.0.0
 * @since 2025/3/31
 */
public class BuildQuery {

    private static final Logger logger = org.slf4j.LoggerFactory.getLogger(BuildQuery.class);

    public static void execute(TableInfo tableInfo) {
        File folder = new File(Constants.PATH_QUERY);
        if (!folder.exists()) {
            folder.mkdirs();
        }
        String className = tableInfo.getBeanName() + Constants.SUFFIX_BEAN_QUERY;
        File poFile = new File(folder, className + ".java");

        OutputStream out = null;
        OutputStreamWriter outWriter = null;
        BufferedWriter bw = null;


        try {
            out = new FileOutputStream(poFile);
            outWriter = new OutputStreamWriter(out, "utf8");
            bw = new BufferedWriter(outWriter);

            bw.write("package " + Constants.PACKAGE_QUERY + ";");
            bw.newLine();
            bw.newLine();


            if (tableInfo.isHaveDate() || tableInfo.isHaveDateTime()) {
                bw.write("import java.util.Date;");
                bw.newLine();


            }

            if (tableInfo.isHaveBigDecimal()) {
                bw.write("import java.math.BigDecimal;");
            }
            bw.newLine();
            bw.newLine();
            //构建类注释
            BuildComment.createClassComment(bw, tableInfo.getComment() + "查询对象");
            bw.write("public class " + className + "{ ");
            bw.newLine();

            List<FiledInfo> extendList = new ArrayList<>();
            for (FiledInfo filed : tableInfo.getFiledList()) {
                BuildComment.createFieldComment(bw, filed.getComment());
                bw.write("\tprivate " + filed.getJavaType() + " " + filed.getPropertyName() + ";");
                bw.newLine();
                bw.newLine();
                //String类型的参数
                if (ArrayUtils.contains(Constants.SQL_STRING_TYPES, filed.getSqlType())) {
                    bw.write("\t/**");
                    bw.newLine();
                    bw.write("\t * @param " + filed.getPropertyName() + " 模糊查询");
                    bw.newLine();
                    bw.write("\t */");
                    bw.newLine();
                    String propertyName = filed.getPropertyName() + Constants.SUFFIX_BEAN_QUERY_FUZZY;
                    bw.write("\tprivate " + filed.getJavaType() + " " + propertyName + ";");
                    bw.newLine();
                    bw.newLine();

                    FiledInfo fuzzyField = new FiledInfo();
                    fuzzyField.setJavaType(filed.getJavaType());
                    fuzzyField.setPropertyName(propertyName);
                    extendList.add(fuzzyField);

                }
                if (ArrayUtils.contains(Constants.SQL_DATE_TIME_TYPES, filed.getSqlType()) || ArrayUtils.contains(Constants.SQL_DATE_TYPES, filed.getSqlType())) {
                    bw.write("\tprivate String " + filed.getPropertyName() + Constants.SUFFIX_BEAN_QUERY_TIME_START + ";");
                    bw.newLine();
                    bw.newLine();
                    bw.write("\tprivate String " + filed.getPropertyName() + Constants.SUFFIX_BEAN_QUERY_TIME_END + ";");
                    bw.newLine();
                    bw.newLine();

                    FiledInfo timeStartField = new FiledInfo();
                    timeStartField.setJavaType("String");
                    timeStartField.setPropertyName(filed.getPropertyName() + Constants.SUFFIX_BEAN_QUERY_TIME_START);
                    extendList.add(timeStartField);

                    FiledInfo timeEndField = new FiledInfo();
                    timeEndField.setJavaType("String");
                    timeEndField.setPropertyName(filed.getPropertyName() + Constants.SUFFIX_BEAN_QUERY_TIME_END);
                    extendList.add(timeEndField);
                }
            }
            List<FiledInfo> filedInfoList = tableInfo.getFiledList();
            filedInfoList.addAll(extendList);
            //getter setter
            for (FiledInfo filed : tableInfo.getFiledList()) {
                String tempField = StringUtils.upperCaseFirstLetter(filed.getPropertyName());
                bw.write("\tpublic void set" + tempField + " (" + filed.getJavaType() + " " + filed.getPropertyName() + ") {");
                bw.newLine();
                bw.write("\t\tthis." + filed.getPropertyName() + " = " + filed.getPropertyName() + ";");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();

                bw.write("\tpublic " + filed.getJavaType() + " get" + tempField + "() {");
                bw.newLine();
                bw.write("\t\treturn this." + filed.getPropertyName() + ";");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();
            }
            bw.write("}");
            bw.flush();
        } catch (Exception e) {
            logger.error("生成PO失败", e);
        } finally {
            if (bw != null) {
                try {
                    bw.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (outWriter != null) {
                try {
                    outWriter.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (out != null) {
                try {
                    out.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
